package com.xhwl.centiotdata.suppliersystem.eesd.growatt;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.constant.EesdConstant;
import com.xhwl.centiotdata.utils.LocalDateTimeUtils;
import com.xhwl.centiotdata.utils.ReadJsonUtils;
import com.xhwl.centiotdata.utils.RedisUtils;
import com.xhwl.common.dto.cent.iotdata.growatt.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Copyright: Copyright (c) 2021  ALL RIGHTS RESERVED.
 * @Company: 深圳市兴海物联科技有限公司
 * @Author: gyc
 * @CreateDate: 2021/12/22 10:26
 * @UpdateDate: 2021/12/22 10:26
 * @UpdateRemark: init
 * @Version: 1.0
 */
@Slf4j
@Component
public class GrowattUtil {

    @Resource
    private RedisUtils redisUtils;

    /**
     * 光伏模块公共方法
     *
     * @param growattReqDTO 请求url等
     * @param reqType       请求方式：0-get 1-post
     * @return 返回data
     */
    private String getGrowatt(GrowattReqDTO growattReqDTO, Integer reqType) {
        // 缓存key后缀，实际为 项目id+缓存key后缀
        Integer projectId = growattReqDTO.getProjectId();
        String key = projectId + ":" + growattReqDTO.getKey();
        String url = growattReqDTO.getUrl();
        Integer validTime = growattReqDTO.getValidTime();

        if (validTime == null) {
            // 访问频率限制5分钟/次（通用）
            validTime = EesdConstant.HALF_AN_HOUR;
        }

        Object obj = redisUtils.get(key);
        if (ObjectUtils.isEmpty(obj)) {
            String resp;
            if (reqType.equals(EesdConstant.NUM_0)) {
                resp = HttpRequest.get(url)
                        .header(EesdConstant.HEADER_TOKEN, growattReqDTO.getToken())
                        .execute().body();
            } else {
                resp = HttpRequest.post(url)
                        .header(EesdConstant.HEADER_TOKEN, growattReqDTO.getToken())
                        .execute().body();
            }
            if (!StringUtils.isEmpty(resp)) {
                GrowattRespDTO respDTO = JSONObject.parseObject(resp, GrowattRespDTO.class);
                Integer errorCode = respDTO.getError_code();
                if (errorCode.equals(EesdConstant.NUM_0)) {
                    String data = respDTO.getData();
                    redisUtils.setWithMinute(key, data, validTime);
                } else {
                    String errorMsg = respDTO.getError_msg();
                    log.error("Abnormal pull of photovoltaic data: projectId:{}, url:{}, code:{}, msg:{}",
                            projectId, url, respDTO.getError_code(), errorMsg);
                    throw new RuntimeException(errorMsg);
                }
            } else {
                log.error("Abnormal pull of photovoltaic data: projectId:{}, url:{}", projectId, url);
                throw new RuntimeException("Abnormal pull of photovoltaic data" + projectId);
            }
        }
        obj = redisUtils.get(key);
        if (ObjectUtils.isEmpty(obj)) {
            return null;
        }
        return obj.toString();
    }

    private String getGrowattV1(GrowattReqDTO growattReqDTO, Integer reqType) {
        // 缓存key后缀，实际为 项目id+缓存key后缀
        Integer projectId = growattReqDTO.getProjectId();
        String key = projectId + ":" + growattReqDTO.getKey();
        String url = growattReqDTO.getUrl();
        int validTime = 24 * 60;
        // 先请求最新数据，获取不到使用缓存，再取不到等待下一次获取
        String resp = null;
        try {
            if (reqType.equals(EesdConstant.NUM_0)) {
                resp = HttpRequest.get(url)
                        .header(EesdConstant.HEADER_TOKEN, growattReqDTO.getToken())
                        .execute().body();
            } else {
                resp = HttpRequest.post(url)
                        .header(EesdConstant.HEADER_TOKEN, growattReqDTO.getToken())
                        .execute().body();
            }
        } catch (Exception e) {
            log.error("Abnormal pull of photovoltaic data: projectId:{}, url:{},msg:{}",
                    projectId, url, e.getMessage());
        }

        log.info("光伏调用情况：now:{}, url:{}, token:{}, resp:{}, ", LocalDateTime.now(), url, growattReqDTO.getToken(), resp);

        // 更新缓存
        if (!StringUtils.isEmpty(resp)) {
            GrowattRespDTO respDTO = JSONObject.parseObject(resp, GrowattRespDTO.class);
            Integer errorCode = respDTO.getError_code();
            if (errorCode.equals(EesdConstant.NUM_0)) {
                String data = respDTO.getData();
                redisUtils.setWithMinute(key, data, validTime);
            } else {
                String errorMsg = respDTO.getError_msg();
                log.error("Abnormal pull of photovoltaic data: projectId:{}, url:{}, code:{}, msg:{}",
                        projectId, url, respDTO.getError_code(), errorMsg);
                throw new RuntimeException(errorMsg);
            }
        }

        // 继续使用缓存数据
        Object obj = redisUtils.get(key);
        if (ObjectUtils.isEmpty(obj)) {
            log.error("光伏继续使用缓存数据也异常");
            throw new RuntimeException("光伏继续使用缓存数据也异常");
        }
        // 防止解析异常
        String body = JSONObject.toJSONString(obj);
        Object obj1 = JSON.parse(body);
        return obj1.toString();
    }

    /**
     * 获取某电站数据概览
     *
     * @return
     */
    public GrowattDataRespDTO getPlanData(GrowattReqConfigDTO config) {
        GrowattReqDTO dto = new GrowattReqDTO();
        dto.setProjectId(config.getProjectId());
        dto.setKey(EesdConstant.GROWATT_PLANT_DATA);
        dto.setToken(config.getToken());
        dto.setUrl(config.getHost() + config.getPlantDataUrl());
        String plant = getGrowattV1(dto, EesdConstant.NUM_0);
        if (StringUtils.isEmpty(plant)) {
            return null;
        }
        GrowattDataRespDTO resp = JSONObject.parseObject(plant, GrowattDataRespDTO.class);
        log.info("获取电站概览数据:  {}", JSONObject.toJSONString(resp));
        return resp;
    }

    /**
     * 获取逆变器最新实时数据（3.3接口中返回的设备类型为4的设备：单max）
     *
     * @return JSONObject
     */
    public GrowattDataRespDTO getInverterRealTime(GrowattReqConfigDTO config) {
        GrowattReqDTO dto = new GrowattReqDTO();
        dto.setProjectId(config.getProjectId());
        dto.setKey(EesdConstant.GROWATT_INVERTER_REAL_TIME);
        dto.setToken(config.getToken());
        dto.setUrl(config.getHost() + config.getInverterUrl());
        String max = getGrowattV1(dto, EesdConstant.NUM_1);
        if (StringUtils.isEmpty(max)) {
            return null;
        }
        GrowattDataRespDTO data = JSONObject.parseObject(max, GrowattDataRespDTO.class);
        log.info("获取逆变器最新实时数据:  {}", JSONObject.toJSONString(data));
        return data;
    }

    /**
     * 获取环境检测仪实时数据
     *
     * @return
     */
    public GrowattEnvRespDTO getEnvRealTime(GrowattReqConfigDTO config) {
        GrowattReqDTO dto = new GrowattReqDTO();
        dto.setProjectId(config.getProjectId());
        dto.setKey(EesdConstant.GROWATT_ENV_REAL_TIME);
        dto.setToken(config.getToken());
        dto.setUrl(config.getHost() + config.getEnvRealUrl());
        String env = getGrowattV1(dto, EesdConstant.NUM_0);
        if (StringUtils.isEmpty(env)) {
            return null;
        }
        GrowattEnvRespDTO resp = JSONObject.parseObject(env, GrowattEnvRespDTO.class);
        log.info("获取环境检测仪实时数据:  {}", JSONObject.toJSONString(resp));
        return resp;
    }

    /**
     * 获取环境检测仪历史数据(累计辐照度)
     *
     * @return
     */
    public String getTotalRadiant(GrowattReqConfigDTO config) {
        GrowattReqDTO dto = new GrowattReqDTO();
        dto.setProjectId(config.getProjectId());
        dto.setKey(EesdConstant.GROWATT_ENV);
        dto.setToken(config.getToken());
        String date = LocalDateTimeUtils.getYearMonthDay();
        String envUrl = config.getEnvUrl().replace("{startDate}", date).replace("{endDate}", date);

        dto.setUrl(config.getHost() + envUrl);
        dto.setValidTime(EesdConstant.HALF_AN_HOUR);

        String env = getGrowattV1(dto, EesdConstant.NUM_0);

        if (StringUtils.isEmpty(env)) {
            return null;
        }
        GrowattDataRespDTO data = JSONObject.parseObject(env, GrowattDataRespDTO.class);
        String envData = data.getEnv_data();
        List<GrowattEnvRespDTO> list = JSONObject.parseArray(envData, GrowattEnvRespDTO.class);
        GrowattEnvRespDTO growattEnvRespDTO = list.get(0);
        String radiant = growattEnvRespDTO.getRadiant();
        log.info("获取环境检测仪历史数据:  {}", radiant);
        return radiant;
    }

    /**
     * 获取某个逆变器报警数据
     *
     * @return
     */
    public GrowattAlramDataRespDTO getInverterAlarm(GrowattReqConfigDTO config) {
        GrowattReqDTO dto = new GrowattReqDTO();
        dto.setProjectId(config.getProjectId());
        dto.setKey(EesdConstant.GROWATT_INVERTER_ALARM);
        dto.setToken(config.getToken());
        dto.setUrl(config.getHost() + config.getInverterAlarmUrl()
                .replace("{date}", LocalDateTimeUtils.getYearMonthDay()));
        String maxAlarm = getGrowattV1(dto, EesdConstant.NUM_1);
        if (StringUtils.isEmpty(maxAlarm)) {
            return null;
        }
        GrowattAlramDataRespDTO data = JSONObject.parseObject(maxAlarm, GrowattAlramDataRespDTO.class);
        Integer count = data.getCount();
        log.info("Get the number of inverter alarm data:  {}", count);
        return data;
    }

    /**
     * 获取设备列表
     *
     * @return
     */
    public List<GrowattDeviceRespDTO> getDeviceList(GrowattReqConfigDTO config) {
        GrowattReqDTO dto = new GrowattReqDTO();
        dto.setProjectId(config.getProjectId());
        dto.setKey(EesdConstant.GROWATT_DEVICE_LIST);
        dto.setToken(config.getToken());
        dto.setUrl(config.getHost() + config.getDeviceListUrl()
                .replace("{date}", LocalDateTimeUtils.getYearMonthDay()));
        String deviceList = getGrowattV1(dto, EesdConstant.NUM_0);
        if (StringUtils.isEmpty(deviceList)) {
            return null;
        }
        log.info("Get the deviceList data:  {}", deviceList);
        List<GrowattDeviceRespDTO> data = JSONObject.parseObject(deviceList, GrowattDeviceListRespDTO.class).getDevices();
        if (!CollectionUtils.isEmpty(data)) {
            data = data.stream().filter(e -> e.getType() .equals(4)).collect(Collectors.toList());
        }
        log.info("Get the deviceList data:  {}", data);
        return data;
    }
}

